package com.jchy.renderit.core;
 
public class Camera
{

	@MaxValue(1.0)
	@MinValue(0.0)
    public Matrix viewMat;
    private Point prp;
    private Point lookat;
    
    
	@MaxValue(1.0)
	@MinValue(0.0)
    public double invZoom;

    private Dir down;
	
	/**
	 * Constructor for Camera.
	 */
	public Camera() {
		super();
        viewMat=new Matrix();
        down=new Dir(0.0, 1.0, 0.0);
        invZoom=0.5;
        lookat=new Point(0.0, 0.0, 0.0);
		prp=new Point(0.0,0.0,-1.0);
		setupView();
	}

	public String toString()
	{
		String result="Center: "+prp+"\n";
		result=result+"Looking At: "+lookat+"\n";
		result=result+"Zoom: "+String.valueOf(invZoom)+"\n";
		result=result+"Down Vector: "+down.toString()+"\n";
		result=result+"Matrix: "+viewMat;
		
		return result;
	}

	/**
	 * Sets the view
	 */
	public void setupView()
	{
        Dir n = prp.toDir(lookat);
        n.normalize();
        Dir u = down.cross(n);
        Dir v = n.cross(u);
        viewMat.Orient(u,v,n);
        viewMat.setorigin(prp.x,prp.y,prp.z);
	}

	/**
	 * Returns the invZoom.
	 * @return double
	 */
	public double getInvZoom() {
		return invZoom;
	}

	/**
	 * Returns the lookat.
	 * @return Point
	 */
	public Point getLookat() {
		return lookat;
	}

	/**
	 * Returns the prp.
	 * @return Point
	 */
	public Point getPrp() {
		return prp;
	}

	/**
	 * Returns the viewMat.
	 * @return Matrix
	 */
	public Matrix getViewMat() {
		return viewMat;
	}

	@MaxValue(1.0)
	@MinValue(0.0)
	public void setInvZoom(double invZoom) {
		if((invZoom > 0) && (invZoom < 1.0))
			this.invZoom = invZoom;
		else
			this.invZoom=0.5;
	}

	/**
	 * Sets the lookat.
	 * @param lookat The lookat to set
	 */
	public void setLookat(Point lookat) {
		this.lookat = lookat;
		setupView();
	}

	public void setLookat(double x, double y, double z)
	{
		setLookat(new Point(x,y,z));
	}

	/**
	 * Sets the prp.
	 * @param prp The prp to set
	 */
	public void setPrp(Point prp) {
		this.prp = prp;
		setupView();
	}


	public void setPrp(double x, double y, double z)
	{
		setPrp(new Point(x,y,z));
	}

	/**
	 * Sets the viewMat.
	 * @param viewMat The viewMat to set
	 */
	public void setViewMat(Matrix viewMat) {
		this.viewMat = viewMat;
	}

	/**
	 * Returns the down.
	 * @return Dir
	 */
	public Dir getDown() {
		return down;
	}

	/**
	 * Sets the down.
	 * @param down The down to set
	 */
	public void setDown(Dir down) {
		this.down = down;
		setupView();
	}

}